﻿using System.IO;
using System.Linq;
using DBFile.Core.Interfaces;
using System;

namespace DBFile.Providers.Impl
{
    public class FileSystemClient : IDBFileProvider
    {
        private const int Success = 1;
        private const int Fail = 0;
        private const string CurrentDirectory = ".";

        private string repositoryPath;

        public FileSystemClient(string repositoryPath)
        {
            if (repositoryPath == CurrentDirectory)
            {
                this.repositoryPath = Environment.CurrentDirectory;
            }
            else
            {
                this.repositoryPath = repositoryPath;
            }
        }
        
        public bool Exists(string filename)
        {
            return File.Exists(GetFilePath(filename));
        }

        public int Copy(string sourceFilename, string destinationFilename, bool overwrite)
        {
            try
            {
                File.Copy(GetFilePath(sourceFilename), GetFilePath(destinationFilename), overwrite);
            }
            catch
            {
                return Fail;
            }
            return Success;
        }

        public int Insert(string filename, byte[] buffer, string contentType, long contentLength)
        {
            try
            {
                File.WriteAllBytes(GetFilePath(filename), buffer);
            }
            catch
            {
                return Fail;
            }
            return Success;
        }

        public int Insert(string filename, byte[] buffer, string contentType, long contentLength, bool overwrite)
        {
            try
            {
                if (!overwrite && File.Exists(GetFilePath(filename)))
                {
                    return Fail;
                }
                else
                {
                    File.WriteAllBytes(GetFilePath(filename), buffer);
                }
            }
            catch
            {
                return Fail;
            }
            return Success;
        }

        public int Update(string filename, byte[] buffer, string contentType, long contentLength)
        {
            try
            {
                File.WriteAllBytes(GetFilePath(filename), buffer);
            }
            catch
            {
                return Fail;
            }
            return Success;
        }

        public int Delete(string filename)
        {
            try
            {
                if (File.Exists(GetFilePath(filename)))
                {
                    File.Delete(GetFilePath(filename));
                }
                else
                {
                    return Fail;
                }
            }
            catch
            {
                return Fail;
            }
            return Success;
        }

        public string[] GetFileNameList()
        {
            return (from fileName in Directory.GetFiles(repositoryPath)
                    select Path.GetFileName(fileName)).ToArray();
        }

        public T Get<T>(string filename) where T : IDBFile, new()
        {
            T file = new T();

            FileStream fs = File.Open(GetFilePath(filename), FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            try
            {
                file.FileName = filename;
                file.ContentLength = fs.Length;
                file.ContentType = DBFile.Core.DBFile.GetContentType(Path.GetExtension(filename));

                file.FileBytes = new byte[fs.Length];
                fs.Read(file.FileBytes, 0, (int)fs.Length);

            }
            finally
            {
                fs.Close();
            }
            return file;
        }

        public string GetFilePath(string filename)
        {
            return Path.Combine(repositoryPath, filename);
        }

    }
}
